package com.atguigu.tingshu.album.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.service.AlbumAttributeValueService;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.cache.TsCache;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.service.KafkaService;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.v3.core.util.Json;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.Nullable;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {


    @Resource
    private AlbumAttributeValueMapper albumAttributeValueMapper;

    @Resource
    private AlbumAttributeValueService albumAttributeValueService;

    @Resource
    private AlbumStatMapper albumStatMapper;

    @Resource
    private KafkaService kafkaService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private RedissonClient redissonClient;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {
        //保存专辑信息
        //封装专辑信息
        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        //设置用户id
        albumInfo.setUserId(1L);
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        //判断专辑是否付费
        if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(albumInfoVo.getPayType())) {
            albumInfo.setTracksForFree(5);
        }
        this.baseMapper.insert(albumInfo);
        //	保存专辑属性值：
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        //保存专辑的标签
        if (!CollectionUtils.isEmpty(albumAttributeValueVoList)) {
            List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueVoList.stream().map(item -> {
                AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                BeanUtils.copyProperties(item, albumAttributeValue);
                albumAttributeValue.setAlbumId(albumInfo.getId());
                return albumAttributeValue;
            }).toList();
            //批量保存专辑属性
            albumAttributeValueService.saveBatch(albumAttributeValues);
        }
        //保存专辑的浏览量和播放量等值
        //初始化统计数据
        //播放量
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_PLAY);
        //订阅量
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_SUBSCRIBE);
        //购买量
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_BROWSE);
        //评论数
        this.saveAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_COMMENT);
        //	发送上架消息
        if ("1".equals(albumInfo.getIsOpen())){
            kafkaService.sendMessage(String.valueOf(albumInfo.getId()),KafkaConstant.QUEUE_ALBUM_UPPER);
        }
    }

    @Override
    public IPage<AlbumListVo> findUserAlbumPage(Page<AlbumListVo> albumListVoPage, AlbumInfoQuery albumInfoQuery) {
        return this.baseMapper.selectUserAlbumPage(albumListVoPage, albumInfoQuery);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeAlbumInfo(Long albumId) {
        //	删除专辑表的数据 album_info
        this.removeById(albumId);
        //	删除专辑属性信息
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        //	删除专辑对应的统计数据
        albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, albumId));
        //下架
        kafkaService.sendMessage(albumId.toString(),KafkaConstant.QUEUE_ALBUM_LOWER);
    }

    @Override
    @TsCache(prefix = RedisConstant.ALBUM_INFO_PREFIX)
    public AlbumInfo getAlbumInfo(Long albumId) {
        return this.getAlbumInfoDB(albumId);
    }

    @Nullable
    private AlbumInfo getAlbumInfoDB(Long albumId) {
        AlbumInfo albumInfo = this.getById(albumId);
        //还要回显属性值集合
        if (albumInfo != null) {
            List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueMapper
                    .selectList(new LambdaQueryWrapper<AlbumAttributeValue>()
                            .eq(AlbumAttributeValue::getAlbumId, albumId));
            albumInfo.setAlbumAttributeValueVoList(albumAttributeValues);
        }
        return albumInfo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateAlbumInfo(Long albumId, AlbumInfoVo albumInfoVo) {
        //向album_info表中根据id修改数据包，
        //构造实体类
        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        albumInfo.setId(albumId);
        this.updateById(albumInfo);
        //修改专辑对应的属性值表album_attribute_value
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        //	先删除专辑属性数据
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        //构造专辑属性集合
        if (!CollectionUtils.isEmpty(albumAttributeValueVoList)) {
            List<AlbumAttributeValue> albumAttributeValues = albumAttributeValueVoList.stream().map(item -> {
                AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
                BeanUtils.copyProperties(item, albumAttributeValue);
                albumAttributeValue.setAlbumId(albumId);
                return albumAttributeValue;
            }).toList();
            //批量保存专辑属性
            albumAttributeValueService.saveBatch(albumAttributeValues);
        }
        //判断当前专辑是否为私密,如果不是就将其上架，如果是需要将专辑下架
        if("1".equals(albumInfo.getIsOpen())) {
            kafkaService.sendMessage(String.valueOf(albumInfo.getId()),KafkaConstant.QUEUE_ALBUM_UPPER);
        } else {
            kafkaService.sendMessage(String.valueOf(albumInfo.getId()),KafkaConstant.QUEUE_ALBUM_LOWER);
        }
    }

    @Override
    public List<AlbumInfo> findUserAllAlbumList(Long userId) {
        // 默认查看第一页
        Page<AlbumInfo> albumInfoPage = new Page<>(1, 100);
        // 设置查询条件
        LambdaQueryWrapper<AlbumInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(AlbumInfo::getId, AlbumInfo::getAlbumTitle);
        wrapper.eq(AlbumInfo::getUserId, userId);
        wrapper.orderByDesc(AlbumInfo::getId);
        wrapper.last(" limit 100");
        return this.baseMapper.selectList(wrapper);
    }

    @Override
    public List<AlbumAttributeValue> findAlbumAttributeValue(Long albumId) {
        List<AlbumAttributeValue> list = albumAttributeValueMapper
                .selectList(new LambdaQueryWrapper<AlbumAttributeValue>()
                        .eq(AlbumAttributeValue::getAlbumId,albumId));
        return list;
    }

    @Override
    @TsCache(prefix = "album:stat:")
    public AlbumStatVo getAlbumStatVo(Long albumId) {
        return this.baseMapper.selectAlbumStat(albumId);
    }

    private void saveAlbumStat(Long id, String albumStatPlay) {
        AlbumStat albumStat = new AlbumStat();
        albumStat.setAlbumId(id);
        albumStat.setStatType(albumStatPlay);
        albumStat.setStatNum(0);
        albumStatMapper.insert(albumStat);
    }
}
